package com.nameli.admin.config.shiro;

import cn.hutool.core.bean.BeanUtil;
import com.nameli.SIM.bean.entity.sys.SysPermission;
import com.nameli.SIM.bean.entity.sys.SysRole;
import com.nameli.SIM.bean.entity.sys.SysToken;
import com.nameli.SIM.bean.entity.sys.SysUser;
import com.nameli.SIM.bean.vo.LoginVo;
import com.nameli.SIM.util.EmptyUtil;
import com.nameli.SIM.util.RedisUtil;
import com.nameli.admin.config.shiro.auth.AuthToken;
import com.nameli.admin.config.shiro.auth.TokenGenerator;
import com.nameli.admin.service.SysUserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author NAME-L
 * @Description 自定义领域类
 * @className MyShiroRealm
 * @date 2021-12-27 11:16:15
 */
public class MyShiroRealm extends AuthorizingRealm {
    private static final Log logger = LogFactory.getLog(MyShiroRealm.class);

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private RedisUtil redisUtil;


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("开始身份验证");
        //1.获取前端传来的token
        String token = (String) authenticationToken.getPrincipal();
        Long userId = TokenGenerator.getUserId(token);
        logger.info("userId:" + userId);
        //2.根据token判断redis中是否存在
        boolean hasKey = redisUtil.hasKey(token);
        LoginVo loginVo = null;
        if (hasKey){
            //3.根据token从redis中查找对应的用户信息
            loginVo = (LoginVo) redisUtil.get(token);
            //4，如果用户不存在，抛出异常
            if (loginVo == null) {
                throw  new UnknownAccountException("用户不存在");
            }
        }else {
            //5，如果token不存在，抛出异常
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }
        SysUser sysUser = BeanUtil.toBean(loginVo, SysUser.class);
        //将信息放到认证通过信息中去
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                sysUser,
                token,
                getName());
        //设置密码盐
//        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(userInfo.getCredentialsSalt()));
        return authenticationInfo;
    }


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.info("开始权限配置");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo ();
        //1.从认证信息中获取当前的用户信息
        SysUser userInfo = (SysUser) principals.getPrimaryPrincipal();
        //2.根据用户名获取对应的角色信息
        List<SysRole> roles = sysUserService.getAllRolesByName(userInfo.getUserName());
        //3.把角色信息放到授权信息中去
        for (SysRole role : roles) {
            info.addRole(role.getRoleKey());
        }
        //4. 根据用户名获取对应的权限信息
        List<SysPermission> permissions = sysUserService.getAllPermissionsByName(userInfo.getUserName());
        //5.把权限信息放到授权信息中去
        for (SysPermission perm : permissions) {
            info.addStringPermission(perm.getPerms());
        }
        return info;
    }

}
